#ifndef __NPC_Entity_H_
#define __NPC_Entity_H_

#include <irrlicht.h>
#include <iostream>

#include <cmath>

#include "Memory.h"
#include "AnimatedEntity.h"
#include "LivingEntity.h"
#include "debug.h"
#include "Desires.h"
#include "Plan.h"


using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

class Memory;
class Plan ;

/*!
	This class provides a NPC Entity. I don't think it should be sub-typed since from there, just the BDI should be implemented. This class provides to the NCP a memory, an hostility list and desires... so much things to add...
	This class is currently under construction, so many things here can be yet unstable.
*/
class NPCEntity: virtual public AnimatedEntity, virtual public LivingEntity
{
	public:
	vector3df target_seek__; /**< Temporary variable used to display seeking target */
	vector3df pwetpwet;      /**< temporary variable used to debug seeking. In fact, it may not be used anymore. */
	bool pwetpwet__;         /**< Temporary variable used to debug seeking. In fact, it may not be used anymore. */

	protected:
	Memory memory__;		/**< Memory of the Entity. */
	Desires desires__ ;		/**< Desires of the Entity. */
	Plan plan__ ;			/**< Plan for the future */
	int frameCounter__ ; 		/**< Count the frame since the last processing (processing is called every 7 frames) */

	public:
	/*! Constructor. For now it just initializes the desires__ with a BehaviourTemplate (check for Desires class for details) and what is needed for AnimatedEntity. Note that no arguments are given to initialize the inherited LivingEntity things. */
	NPCEntity(const std::string& BehaviourTemplate, const irr::core::string<c8>& entityModel, const irr::core::string<c8>& entitySkin, const irr::core::string<c8>& weaponModel="", const irr::core::string<c8>& weaponSkin="");
	/*! Destructor. For now, does nothing. */
	virtual ~NPCEntity();

	/*! This medhod updates what must be done for the next frame (makes the AI to work a little); but it does nothing really interesting for now. */
	virtual void update();
	/*! This method senses around the NCP for some other Entities it could see, according to its field of vision and vision distance. This method directly updates the NPC's memory__. */
	virtual void senseArea(float distance=400.0, float fovy=80.0, float stepy=10.0, float fovz=30.0, float stepz=15.0);

	/*! Function used to randomize the decision of which desire to satisfy */
	virtual std::pair<std::string,float> RandomizeDecision() ;

	/*! decision function, using Beliefs and Desires to choose a plan */
	virtual void makeDecisionFromBeliefsAndDesires();

	/*! returns the desires of the NPC */
	virtual Desires* getDesires() ;
	
	/*! returns the map of all npc's memories */
	virtual Memory* getMemory() ;

	/*! returns the plan structure */
	virtual Plan* getPlan();

	/*! in case a plan has been achieved sucessfully, apply the correct reward. */
	virtual void getRewardForAchievedPlan(Plan * p);

	/*! this function analyses the state and adjusts desires */
	virtual void processState();

	/*! this function analyses and messages received by the entity and adjusts beliefs and desires */
	virtual void processMessages();

	/*! This function analyses the perception and adjust desires to be satisfied */
	virtual void processMemory();

};

#endif
